#ifndef __DALELIB_MESHLOADERS_H__
#define __DALELIB_MESHLOADERS_H__

#include <assert.h>
#include <string>
#include <vector>
#include <iostream>
#include <fstream>
using namespace std;

#include <dalelib/v2.h>
#include <dalelib/v3.h>
#include <dalelib/m4.h>
#include <dalelib/staticmesh.h>

namespace dalelib
{

Mesh* loadPLY(const string _FileName)
{
	Mesh* m;

	m = loadPLY(_FileName);

	if(m)
	{
//		m->calcNormals();
		return m;
	}
	return 0;
}

//****************************************************************
Mesh* createTetrahedron()
{
	Mesh* m = new Mesh();

	m->getVertices().push_back(v3(-1,-1,-1)); // 0
	m->getVertices().push_back(v3( 1,-1, 1)); // 1
	m->getVertices().push_back(v3(-1, 1, 1)); // 2
	m->getVertices().push_back(v3( 1, 1,-1)); // 3

	m->getTriangles().push_back( Mesh::Triangle(0,3,2) );
	m->getTriangles().push_back( Mesh::Triangle(0,1,3) );
	m->getTriangles().push_back( Mesh::Triangle(1,2,3) );
	m->getTriangles().push_back( Mesh::Triangle(0,1,2) );

	m->calcNormals();

	return m;
}

//****************************************************************
Mesh* loadPLY(const string _FileName)
{
	Mesh* m = new Mesh();
void Mesh::loadPLY(const string _Name)
{
	if( _loaded ) { cout << "mesh already loaded" << endl; return; }
	_loaded = true;

	string str;
	ifstream fin( _Name.c_str() );
	if( !fin ) { cout << "cant load mesh file" << endl; return; }

	int num_triangles;

//	int components[11]; // x,y,z,nx,ny,nz,r,g,b,s,t
	int component_order[11];
	memset(component_order,11*sizeof(int),1);
	int num_components = 0;

	while( str.compare("end_header") )
	{
		fin >> str;
		if( !str.compare("element") )
		{
			fin >> str;
			if( !str.compare("vertex") ) fin >> _num_vertices;
			if( !str.compare("face") )   fin >> num_triangles;
		}

		if( !str.compare("property") )
		{
			fin >> str; // "float"
			fin >> str; // component name

			if( !str.compare("x")  ) component_order[num_components++] =  0;
			if( !str.compare("y")  ) component_order[num_components++] =  1;
			if( !str.compare("z")  ) component_order[num_components++] =  2;
			if( !str.compare("nx") ) component_order[num_components++] =  3;
			if( !str.compare("ny") ) component_order[num_components++] =  4;
			if( !str.compare("nz") ) component_order[num_components++] =  5;
			if( !str.compare("r")  ) component_order[num_components++] =  6;
			if( !str.compare("g")  ) component_order[num_components++] =  7;
			if( !str.compare("b")  ) component_order[num_components++] =  8;
			if( !str.compare("s")  ) component_order[num_components++] =  9;
			if( !str.compare("t")  ) component_order[num_components++] = 10;
		}
	}

	_vertexbuffer = new v3[_num_vertices];
	_vertexbufferbase = new v3[_num_vertices];
	_normalbuffer = new v3[_num_vertices];
	_normalbufferbase = new v3[_num_vertices];
	_colourbuffer = new v3[_num_vertices];
	_texcoordbuffer = new v2[_num_vertices];

	for(int i=0; i<_num_vertices; ++i)
	{
		float components[] = { 0,0,0,0,1,0,255,255,255,0,0,}; // defaults
		for(int j=0; j<num_components; ++j)
		{
			fin >> str;
			components[component_order[j]] = atof(str.c_str());
		}

		_vertexbufferbase[i] = _vertexbuffer[i] = v3(components[ 0],components[ 1],components[ 2]);
		_normalbufferbase[i] = _normalbuffer[i] = v3(components[ 3],components[ 4],components[ 5]);
		_colourbuffer[i] = v3(components[ 6],components[ 7],components[ 8])/255;
		_texcoordbuffer[i]  = v2(components[ 9],components[10]);
	}


	vector<Triangle> triangles;

	for(int i=0; i<num_triangles; ++i)
	{
		int v[4];
		fin >> str; int num_verts = atoi(str.c_str());
		for(int j=0; j<num_verts; ++j) { fin >> str; v[j] = atoi(str.c_str()); }
		if( num_verts==3 )
		{
			triangles.push_back(Triangle(v[0],v[1],v[2]));
		}
		else if( num_verts==4 )
		{
			triangles.push_back(Triangle(v[0],v[1],v[2]));
			triangles.push_back(Triangle(v[0],v[2],v[3]));
		}
	}

	_num_indices = triangles.size()*3;
	_indexbuffer = new GLuint[_num_indices];
	for(int ii=0,i=0; i<triangles.size(); ++i)
	{
		_indexbuffer[ii++] = triangles[i].v[0];
		_indexbuffer[ii++] = triangles[i].v[1];
		_indexbuffer[ii++] = triangles[i].v[2];
	}


	fin.close();

	return m;
}


} // namespace dalelib

#endif

